import React, { useState, useRef, useEffect } from 'react';
import MDEditor, { commands, ExecuteState } from '@uiw/react-md-editor';
import styles from './index.module.css';
import { message } from 'antd';
import ImageSelector from '../ImageSelector';

// 导入KaTeX样式
import 'katex/dist/katex.css';

// 导入LaTeX插件
import rehypeKatex from 'rehype-katex';
import remarkMath from 'remark-math';

// 导入模块化功能
import { latexSupport } from './latexSupport';
import { htmlToMarkdown, HtmlToMarkdownConverter } from './htmlToMarkdown';
import { 
  ImageUploadManager, 
  ImageSize, 
  ImageUploadOptions,
  createFileSelector 
} from './imageUpload';

// 创建图片上传管理器实例
const imageUploadManager = new ImageUploadManager();

interface MarkdownEditorProps {
  value?: string;
  onChange?: (value?: string) => void;
  preview?: 'live' | 'edit' | 'preview';
  readOnly?: boolean;
  height?: number;
  placeholder?: string;
}

const MarkdownEditor: React.FC<MarkdownEditorProps> = ({
  value,
  onChange,
  preview = 'live',
  readOnly = false,
  height,
  placeholder,
}) => {
  const safeValue = value || '';
  const [imageSelectorVisible, setImageSelectorVisible] = useState(false);
  const [imageSize, setImageSize] = useState({ width: 300, height: 200 });
  const editorRef = useRef<HTMLDivElement>(null);
  
  // 计算编辑器高度
  const getEditorHeight = () => {
    if (readOnly) return 'auto';
    if (height) return height;
    
    // 根据内容长度动态计算高度
    const contentLines = safeValue.split('\n').length;
    const minHeight = 400; // 最小高度
    const maxHeight = 800; // 最大高度
    const lineHeight = 24; // 每行大约24px
    const calculatedHeight = Math.max(minHeight, Math.min(maxHeight, contentLines * lineHeight + 100));
    
    return calculatedHeight;
  };
  
  // console.log('MDEditor value:', { value, type: typeof value, length: value ? value.length : 0 });
  
  // 处理图片选择
  const handleImageSelect = (url: string) => {
    const filename = imageUploadManager.extractFilename(url);
    const newValue = imageUploadManager.generateImageHTML(url, filename, imageSize);
    if (onChange) {
      onChange(safeValue + newValue);
    }
  };

  // 处理图片上传
  const handleImageUpload = async (file: File) => {
    try {
      const url = await imageUploadManager.uploadImage(file);
      return url;
    } catch (error) {
      message.error('图片上传失败');
      return '';
    }
  };

  // 处理图片大小变化
  const handleSizeChange = (type: 'width' | 'height', value: number | null) => {
    if (value !== null) {
      setImageSize(prev => ({
        ...prev,
        [type]: value
      }));
    }
  };

  // 处理粘贴事件，自动转换HTML为Markdown
  const handlePaste = (event: Event) => {
    const clipboardEvent = event as ClipboardEvent;
    const clipboardData = clipboardEvent.clipboardData;
    if (!clipboardData) return;

    // 检查是否有HTML内容
    const html = clipboardData.getData('text/html');
    const text = clipboardData.getData('text/plain');
    
    //console.log('粘贴事件触发:', { html: html?.substring(0, 100), text: text?.substring(0, 100) });
    
    if (html && html !== text) {
      // 有HTML内容，尝试转换
      clipboardEvent.preventDefault();
      
      try {
        // 检测内容来源
        const source = HtmlToMarkdownConverter.detectSource(html);
        console.log('检测到内容来源:', source);
        
        // 使用新的HTML转换器
        const converter = new HtmlToMarkdownConverter({
          preserveImages: true,
          preserveLinks: true,
          preserveTables: true,
          preserveCodeBlocks: true
        });
        
        const markdown = converter.convert(html);
        
        if (markdown && onChange) {
          // 获取当前光标位置和选中的文本
          const editorElement = editorRef.current?.querySelector('.w-md-editor-text-input') as HTMLTextAreaElement;
          if (editorElement) {
            const start = editorElement.selectionStart;
            const end = editorElement.selectionEnd;
            const currentValue = editorElement.value;
            
            // 在光标位置插入转换后的Markdown
            const newValue = currentValue.substring(0, start) + markdown + currentValue.substring(end);
            
            console.log('更新编辑器值:', { start, end, currentValue: currentValue.length, newValue: newValue.length });
            
            // 更新编辑器内容
            onChange(newValue);
            
            // 设置新的光标位置
            setTimeout(() => {
              const newCursorPos = start + markdown.length;
              editorElement.setSelectionRange(newCursorPos, newCursorPos);
              editorElement.focus();
            }, 0);
          } else {
            // 如果找不到编辑器元素，直接添加到末尾
            const newValue = safeValue + '\n\n' + markdown;
            onChange(newValue);
          }
          
          const sourceText = source === 'yuque' ? '语雀' : source === 'zhihu' ? '知乎' : 'HTML';
          message.success(`已自动将${sourceText}内容转换为Markdown格式`);
        }
      } catch (error) {
        console.error('HTML转Markdown失败:', error);
        message.warning('HTML转换失败，已粘贴原始文本');
      }
    }
  };

  // 检测内容变化，提示LaTeX支持
  useEffect(() => {
    if (safeValue && latexSupport.hasLatexContent(safeValue)) {
      console.log('检测到LaTeX内容:', latexSupport.extractLatexContent(safeValue));
    }
  }, [safeValue]);

  // 添加粘贴事件监听器
  useEffect(() => {
    // 延迟绑定事件，确保编辑器已完全初始化
    const timer = setTimeout(() => {
      const editorElement = editorRef.current?.querySelector('.w-md-editor-text-input');
      if (editorElement && !readOnly) {
        // 先移除可能存在的监听器，避免重复绑定
        editorElement.removeEventListener('paste', handlePaste);
        editorElement.addEventListener('paste', handlePaste);
      }
    }, 100);
    
    return () => {
      clearTimeout(timer);
      // 清理事件监听器
      const editorElement = editorRef.current?.querySelector('.w-md-editor-text-input');
      if (editorElement) {
        editorElement.removeEventListener('paste', handlePaste);
      }
    };
  }, []); // 只在组件挂载时绑定一次
  
  return (
    <div ref={editorRef} className={styles.editor} data-mode={preview}>
      <MDEditor
        value={safeValue}
        onChange={onChange}
        preview={preview}
        hideToolbar={readOnly}
        height={getEditorHeight()}
        visibleDragbar={!readOnly}
        className={readOnly ? styles.readOnlyEditor : ''}
        previewOptions={{
          rehypePlugins: [[rehypeKatex, { output: 'html' }]],
          remarkPlugins: [remarkMath],
          components: {
            img: ({ node, ...props }) => {
              return (
                <img
                  {...props}
                  style={{ 
                    maxWidth: '100%',
                    objectFit: 'contain'
                  }}
                />
              );
            },
          },
        }}
        commands={[
          {
            name: 'image',
            keyCommand: 'image',
            buttonProps: { 'aria-label': '添加图片' },
            icon: <span>🖼️</span>,
            execute: async (state: ExecuteState, api) => {
              const input = createFileSelector();
              
              input.onchange = async (e) => {
                const file = (e.target as HTMLInputElement).files?.[0];
                if (file) {
                  const url = await handleImageUpload(file);
                  if (url) {
                    const newValue = imageUploadManager.generateImageHTML(url, file.name, imageSize);
                    api.replaceSelection(newValue);
                  }
                }
              };
              
              input.click();
            },
          },
          {
            name: 'selectImage',
            keyCommand: 'selectImage',
            buttonProps: { 'aria-label': '选择已有图片' },
            icon: <span>📁</span>,
            execute: () => {
              setImageSelectorVisible(true);
            },
          },
          {
            name: 'inlineMath',
            keyCommand: 'inlineMath',
            buttonProps: { 'aria-label': '插入行内数学公式' },
            icon: <span>∑</span>,
            execute: (state: ExecuteState, api) => {
              api.replaceSelection('$公式$');
            },
          },
          {
            name: 'blockMath',
            keyCommand: 'blockMath',
            buttonProps: { 'aria-label': '插入块级数学公式' },
            icon: <span>∫</span>,
            execute: (state: ExecuteState, api) => {
              api.replaceSelection('\n$$\n公式\n$$\n');
            },
          },
        ]}
      />

      <ImageSelector
        visible={imageSelectorVisible}
        onClose={() => setImageSelectorVisible(false)}
        onSelect={handleImageSelect}
        imageSize={imageSize}
        onSizeChange={handleSizeChange}
      />
    </div>
  );
};

export default MarkdownEditor; 